package com.zh.security.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * @Description: 自定义登录逻辑
 * @ClassName MyUserDetailsService
 * @date: 2021.10.17 14:49
 * @Author: zhanghang
 */
//@Service
@Configuration
public class MyUserDetailsService implements UserDetailsService {

	@Autowired
	private PasswordEncoder passwordEncoder;
	
	/**
	 * description: 该方法的作用就是根据用户名加载用户信息 
	 * date: 2021年-10月-17日 14:50
	 * author: zhanghang
	 * 
	 * @param s
	 * @return org.springframework.security.core.userdetails.UserDetails
	 */ 
	@Override
	public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
		System.out.println("======执行自定义逻辑=====");

		// 1. 根据用户名去数据库中查询用户信息，如果不存在就抛UsernameNotFoundException异常
		if (!"admin".equals(s)){
			throw new UsernameNotFoundException("用户名不存在");
		}

		// 2. 将查询到的用户信息封装到 UserDetails 接口的实现类User 中
		// 这里是假数据，因为存储在数据库中的密码一定是加密过的，所以这里用密码解析器自动加密一下
		String encodePW = passwordEncoder.encode("123");
		// 注意：第一个参数时用户名，第二个参数是密码，第三个参数是权限，多个权限使用','分割
		User user = new User(s,encodePW, AuthorityUtils.commaSeparatedStringToAuthorityList("admin,normal,ROLE_abc"));
		// 也可以使用User的静态内部类 User.UserBuilder 来构建User对象
//		UserDetails userDetails = User.builder()
//				.username(s)
//				.password(encodePW)
//				// 注意：authorities 和 roles，都会存在一个集合中，无非是在role的前面新增‘ROLE_’
//				// 使用User.builder() 的方式构建User ，按照前后执行，后面的权限或角色会覆盖掉前面的权限或角色
//				.authorities("admin","normal")
//				.roles("abc")
//				.build();
		return user;

	}
}
